<template>
    <div class="page">
        <p>散点图</p>
        <button @click="changeData">更新数据</button>
        <div id="container"></div>
    </div>
</template>
<script>
import * as d3 from "d3"
export default {
    data() {
        return {
            dataset: [
                [0.5, 0.5],
                [0.7, 0.8],
                [0.4, 0.9],
                [0.11, 0.32],
                [0.88, 0.25],
                [0.75, 0.12],
                [0.5, 0.1],
                [0.2, 0.3],
                [0.4, 0.1],
                [0.6, 0.7]
            ]
        }
    },
    methods: {
        draw(data) {
            //预先定义好，svg的大小，以及 在svg内部作画的时候 各种padding的值
            let padding = {
                    top: 20,
                    bottom: 20,
                    left: 30,
                    right: 20
                },
                svgWidth = 400,
                svgHeight = 400
            if (!this.circleUpdate) {
                //使用d3创建一个svg元素
                let svg = (this.svg = d3.select("#container").append("svg"))
                //设置svg的宽高
                svg.attr("width", svgWidth).attr("height", svgHeight)
                //定义坐标轴需要的比例尺
                let xScale = d3
                        .scaleLinear()
                        .domain([0, 1.2 * d3.max(data, d => d[0])])
                        .range([0, svgWidth - padding.left - padding.right]),
                    yScale = d3
                        .scaleLinear()
                        .domain([0, 1.2 * d3.max(data, d => d[1])])
                        .range([svgHeight - padding.top - padding.bottom, 0]),
                    eleXAxis = this.svg
                        .append("g")
                        .attr(
                            "transform",
                            `translate(${padding.left},${svgHeight -
                                padding.bottom})`
                        ),
                    eleYAxis = this.svg
                        .append("g")
                        .attr(
                            "transform",
                            `translate(${padding.left},${padding.top})`
                        ),
                    xAxis = d3
                        .axisBottom(xScale)
                        .ticks(5)
                        .tickSizeOuter(0)
                        .tickSizeInner(6),
                    yAxis = d3
                        .axisLeft(yScale)
                        .ticks(5)
                        .tickSizeOuter(0)
                        .tickSizeInner(6)
                //将坐标轴画出来
                xAxis(eleXAxis)
                yAxis(eleYAxis)
                this.xScale = xScale
                this.yScale = yScale
            }
            //y轴坐标反过来映射一次
            this.yScale.range([0, svgHeight])
            let circleUpdate = this.svg.selectAll("circle").data(data),
                enter = circleUpdate.enter(),
                exit = circleUpdate.exit()
            this.circleUpdate = circleUpdate
            this.enter = enter
            this.exit = exit
            this.circleUpdate
                .transition()
                .duration(500)
                .attr("cx", d => {
                    return padding.left + this.xScale(d[0])
                })
                .attr("cy", d => {
                    return svgHeight - (padding.bottom + this.yScale(d[1]))
                })
            this.enter
                .append("circle")
                .attr("fill", "black")
                .attr("cx", () => {
                    return padding.left
                })
                .attr("cy", () => {
                    return svgHeight - padding.bottom
                })
                .attr("r", 5)
                .transition()
                .duration(500)
                .attr("cx", d => {
                    return padding.left + this.xScale(d[0])
                })
                .attr("cy", d => {
                    return svgHeight - (padding.bottom + this.yScale(d[1]))
                })
            this.exit
                .transition()
                .duration(500)
                .attr("fill", "white")
                .remove()
        },
        changeData() {
            this.dataset = [[0.3, 0.7],[0.4, 0.6],[0.5, 0.5],[0.6, 0.4]]
            this.draw(this.dataset)
        }
    },
    mounted() {
        this.draw(this.dataset)
    }
}
</script>
